package com.kelvem.saas.workbanch.core.base;

import com.kelvem.saas.workbanch.core.exception.SaasAssert;
import com.kelvem.saas.workbanch.core.exception.SaasException;
import com.kelvem.saas.workbanch.fsm.dao.BaseDao;
import com.kelvem.saas.workbanch.fsm.entity.Entity;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * BaseService
 *
 * @Author kelvem
 */
public abstract class BaseService<T extends Entity, Q extends BaseQueryVo> {
    
    /**
     * 对象参数构建模板
     * @param queryVo 查询参数
     * @return 构建查询专用对象
     */
    public abstract BaseCriteria<T> buildQueryCriteria(Q queryVo);
    public abstract BaseDao<T> getDao();
    
    /**
     * 分页处理
     * @param queryVo 查询参数
     * @return 查询结果-分页
     */
    public Page<T> queryPage(Q queryVo) {
        BaseCriteria<T> saasCriteria = this.buildQueryCriteria(queryVo);
        Page<T> page = new Page<>(queryVo.getPageNum(), queryVo.getPageSize());
        Page<T> result = this.getDao().selectPage(page, saasCriteria.wrapper());

        return result;
    }

    /**
     * 查询结果集
     * @param queryVo 查询条件
     * @return 结果列表
     */
    public List<T> queryList(Q queryVo) {
        BaseCriteria<T> criteria = buildQueryCriteria(queryVo);
        List<T> list = this.getDao().selectList(criteria.wrapper());
        return list;
    }

    /**
     * 批量merge实体表
     *
     * @param originallist 原始列表
     * @param targetlist 目标列表
     * @return 影响记录数
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer merge(List<T> originallist, List<T> targetlist) {
        SaasAssert.notNull(originallist);
        SaasAssert.notNull(targetlist);
        try {
            int count = 0;
            /** 更新 */
            for (T entity : targetlist) {
                if (entity.getId() != null) {
                    this.getDao().updateById(entity);
                    count++;
                }
            }

            /** 插入 */
            for (T entity : targetlist) {
                if (entity.getId() == null) {
                    this.getDao().insert(entity);
                    count++;
                }
            }

            /** 删除 */
            Map<Long, T> bufMap = new HashMap<>();
            for (T entity : targetlist) {
                if (entity.getId() != null) {
                    bufMap.put(entity.getId(), entity);
                }
            }

            for (T originalEntity : originallist) {
                if (!bufMap.containsKey(originalEntity.getId())) {
                    this.getDao().deleteById(originalEntity.getId());
                    count++;
                }
            }

            return count;
        } catch (Exception e) {
            throw new SaasException(e.getMessage());
        }
    }

    /**
     * 判断对象是否为null,字段串"",null返回false,其它null返回false
     *
     * @param obj 被检查对象
     * @return 空:true, 非空:false
     */
    protected boolean isNotEmpty(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj instanceof String) {
            if (((String) obj).trim().isEmpty()) {
                return false;
            } else {
                return true;
            }
        }
        if (obj instanceof Collection) {
            Collection<?> col = (Collection<?>) obj;
            return !col.isEmpty();
        }
        return true;
    }

    protected  boolean isEmpty(Object obj) {
        return !isNotEmpty(obj);
    }
}
